package gestor;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;

import basedados.Queries;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;

import dados.Accao;
import dados.Registo;
import dados.Stock;
import dados.Utilizador;

public class GestorBD {
	private PreparedStatement preparedStatement;
	private Connection connection;

	public GestorBD(Connection connection) {
		this.connection = connection;
	}

	public Utilizador selectJogador(String email) {
		System.out.println("GestorBD - Email: " + email);
		Utilizador utilizador = null;
		try {
			preparedStatement = (PreparedStatement) connection
					.prepareStatement(Queries.selectUtilizador);
			preparedStatement.setString(1, email);
			ResultSet resultSet = preparedStatement.executeQuery();
			while (resultSet.next()) {
				utilizador = new Utilizador(resultSet.getString("email"),
						resultSet.getString("password"),
						resultSet.getString("nome"),
						resultSet.getDate("datanascimento") + "",
						resultSet.getDouble("saldo"),
						resultSet.getInt("pontos"));
				utilizador.setSuperUser(resultSet.getBoolean("superuser"));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				preparedStatement.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("GestorBD - Utilizador: " + utilizador);
		if (utilizador != null) {
			utilizador.setAccoes(selectAccoesFromUser(utilizador));
		}

		return utilizador;

	}

	public ArrayList<Utilizador> selectAllUtilizadores() {
		ArrayList<Utilizador> utilizadores = new ArrayList<Utilizador>();
		try {
			preparedStatement = (PreparedStatement) connection
					.prepareStatement(Queries.selectAllUtilizadores);
			ResultSet resultSet = preparedStatement.executeQuery();
			while (resultSet.next()) {
				utilizadores.add(new Utilizador(resultSet.getString("email"),
								resultSet.getString("password"), 
								resultSet.getString("nome"), 
								resultSet.getDate("datanascimento") + "",
								resultSet.getDouble("saldo"), 
								resultSet.getInt("pontos")));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				preparedStatement.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return utilizadores;
	}

	public int insertUtilizador(Utilizador u) {
		int row = 0;
		try {
			preparedStatement = (PreparedStatement) connection
					.prepareStatement(Queries.insertUtilizador);
			preparedStatement.setString(1, u.getEmail());
			preparedStatement.setString(2, u.getPassword());
			preparedStatement.setString(3, u.getNome());
			preparedStatement.setObject(4, u.getDatanascimento());
			preparedStatement.setDouble(5, u.getSaldo());
			preparedStatement.setDouble(6, 0);
			preparedStatement.setBoolean(7, u.isSuperUser());
			row = preparedStatement.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return row;
	}
	
	public int deleteUtilizador(Utilizador utilizador) {
		int row = 0;
		try {
			preparedStatement = (PreparedStatement) connection.prepareStatement(Queries.deleteUtilizador);
			preparedStatement.setString(1, utilizador.getEmail());
			row = preparedStatement.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				preparedStatement.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return row;
	}
	
	public ArrayList<Registo> selectRegistos(Utilizador utilizador) {
		ArrayList<Registo> historial = new ArrayList<Registo>();
		try {
			preparedStatement = (PreparedStatement) connection
					.prepareStatement(Queries.selectAllRegistosFromOneUtilizador);
			preparedStatement.setString(1, utilizador.getEmail());
			ResultSet resultSet = preparedStatement.executeQuery();
			Registo registo;
			while (resultSet.next()) {
				registo = new Registo();
				registo.setTimestamp(resultSet.getTimestamp("data"));
				registo.setSigla(resultSet.getString("sigla"));
				registo.setQuantidade(resultSet.getInt("quantidade"));
				registo.setValor(resultSet.getDouble("valor"));
				registo.setCompra_venda(resultSet.getBoolean("valor"));
				historial.add(registo);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				preparedStatement.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return historial;

	}
	
	public ArrayList<Integer> selectSugestoes(Utilizador utilizador) {
		ArrayList<Integer> sugestoes = new ArrayList<Integer>();
		try {
			preparedStatement = (PreparedStatement) connection
					.prepareStatement(Queries.selectSugestaoFromUtilizador);
			preparedStatement.setString(1, utilizador.getEmail());
			ResultSet resultSet = preparedStatement.executeQuery();
			while (resultSet.next()) {
				sugestoes.add(resultSet.getInt("analista"));
				sugestoes.add(resultSet.getInt("vigarista"));
				sugestoes.add(resultSet.getInt("transaccoes"));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				preparedStatement.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return sugestoes;

	}

	public ArrayList<Utilizador> top5Saldo() {
		ArrayList<Utilizador> utilizadores = new ArrayList<Utilizador>();
		try {
			preparedStatement = (PreparedStatement) connection
					.prepareStatement(Queries.selectTop5Saldo);
			ResultSet resultSet = preparedStatement.executeQuery();
			while (resultSet.next()) {
				utilizadores.add(new Utilizador(resultSet.getString("email"),
								resultSet.getString("password"),
								resultSet.getString("nome"), 
								resultSet.getDate("datanascimento") + "",
								resultSet.getDouble("saldo"), 
								resultSet.getInt("pontos")));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				preparedStatement.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		for(Utilizador u : utilizadores){
			u.setValor(u.getSaldo());
		}
		Collections.sort(utilizadores);
		return utilizadores;
	}

	public ArrayList<Utilizador> top5Pontos() {
		ArrayList<Utilizador> utilizadores = new ArrayList<Utilizador>();
		try {
			preparedStatement = (PreparedStatement) connection
					.prepareStatement(Queries.selectTop5Pontos);
			ResultSet resultSet = preparedStatement.executeQuery();
			while (resultSet.next()) {
				utilizadores.add(new Utilizador(resultSet.getString("email"),
						resultSet.getString("password"), resultSet
								.getString("nome"), resultSet
								.getDate("datanascimento") + "", resultSet
								.getInt("saldo"), resultSet.getInt("pontos")));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				preparedStatement.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return utilizadores;
	}

	public ArrayList<Stock> selectStocks() {
		ArrayList<Stock> stocks = new ArrayList<Stock>();
		try {
			preparedStatement = (PreparedStatement) connection
					.prepareStatement(Queries.selectLastStocks);
			ResultSet resultSet = preparedStatement.executeQuery();
			while (resultSet.next()) {
				stocks.add(new Stock(resultSet.getString("nome"), resultSet
						.getString("empresa_sigla"), resultSet
						.getDouble("variacao"), resultSet.getDouble("cotacao"),
						resultSet.getDouble("valoraltodia"), resultSet
								.getDouble("valorbaixodia"), resultSet
								.getInt("volume")));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				preparedStatement.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return stocks;
	}

	public ArrayList<Accao> selectAccoesFromUser(Utilizador utilizador) {
		ArrayList<Accao> accoes = new ArrayList<Accao>();
		try {
			preparedStatement = (PreparedStatement) connection
					.prepareStatement(Queries.selectAccoes);
			preparedStatement.setString(1, utilizador.getEmail());
			ResultSet resultSet = preparedStatement.executeQuery();
			while (resultSet.next()) {
				accoes.add(new Accao(resultSet.getString("nome"), resultSet
						.getString("sigla"), resultSet.getInt("quantidade"),
						resultSet.getDouble("valoraquisicao")));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				preparedStatement.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return accoes;
	}

	public int insertUtilizadorSugestao(Utilizador u) {
		int row = 0;
		try {
			preparedStatement = (PreparedStatement) connection
					.prepareStatement(Queries.insertUtilizadorSugestao);
			preparedStatement.setString(1, u.getEmail());
			row = preparedStatement.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return row;
	}
	
	public int updateSuperUser(Utilizador u) {
		int row = 0;
		try {
			preparedStatement = (PreparedStatement) connection.prepareStatement(Queries.updateUtilizadorSuperUser);
			preparedStatement.setString(1, u.getEmail());
			row = preparedStatement.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return row;
	}
}